// import {
//     callPopup,
//     characters,
//     chat,
//     chat_metadata,
//     crop_data,
//     default_avatar,
//     eventSource,
//     event_types,
//     getCropPopup,
//     getRequestHeaders,
//     getThumbnailUrl,
//     name1,
//     reloadCurrentChat,
//     saveChatConditional,
//     saveMetadata,
//     saveSettingsDebounced,
//     setUserName,
//     this_chid,
// } from '../script.js';
// import { persona_description_positions, power_user } from './power-user.js';
// import { getTokenCountAsync } from './tokenizers.js';
// import { PAGINATION_TEMPLATE, debounce, delay, download, ensureImageFormatSupported, flashHighlight, getBase64Async, parseJsonFile } from './utils.js';
// import { debounce_timeout } from './constants.js';
// import { FILTER_TYPES, FilterHelper } from './filters.js';
// import { selected_group } from './group-chats.js';

// let savePersonasPage = 0;
// const GRID_STORAGE_KEY = 'Personas_GridView';
// const DEFAULT_DEPTH = 2;
// const DEFAULT_ROLE = 0;
export let user_avatar = '';
// export const personasFilter = new FilterHelper(debounce(getUserAvatars, debounce_timeout.quick));

// function switchPersonaGridView() {
//     const state = localStorage.getItem(GRID_STORAGE_KEY) === 'true';
//     $('#user_avatar_block').toggleClass('gridView', state);
// }

/**
 * Returns the URL of the avatar for the given user avatar Id.
 * @param {string} avatarImg User avatar Id
 * @returns {string} User avatar URL
 */
export function getUserAvatar(avatarImg) {
    return `User Avatars/${avatarImg}`;
}

// export function initUserAvatar(avatar) {
//     user_avatar = avatar;
//     reloadUserAvatar();
//     highlightSelectedAvatar();
// }

// /**
//  * Sets a user avatar file
//  * @param {string} imgfile Link to an image file
//  */
// export function setUserAvatar(imgfile) {
//     user_avatar = imgfile && typeof imgfile === 'string' ? imgfile : $(this).attr('imgfile');
//     reloadUserAvatar();
//     highlightSelectedAvatar();
//     selectCurrentPersona();
//     saveSettingsDebounced();
//     $('.zoomed_avatar[forchar]').remove();
// }

// function highlightSelectedAvatar() {
//     $('#user_avatar_block .avatar-container').removeClass('selected');
//     $(`#user_avatar_block .avatar-container[imgfile="${user_avatar}"]`).addClass('selected');
// }

// function reloadUserAvatar(force = false) {
//     $('.mes').each(function () {
//         const avatarImg = $(this).find('.avatar img');
//         if (force) {
//             avatarImg.attr('src', avatarImg.attr('src'));
//         }

//         if ($(this).attr('is_user') == 'true' && $(this).attr('force_avatar') == 'false') {
//             avatarImg.attr('src', getUserAvatar(user_avatar));
//         }
//     });
// }

// /**
//  * Sort the given personas
//  * @param {string[]} personas - The persona names to sort
//  * @returns {string[]} The sorted persona names arrray, same reference as passed in
//  */
// function sortPersonas(personas) {
//     const option = $('#persona_sort_order').find(':selected');
//     if (option.attr('value') === 'search') {
//         personas.sort((a, b) => {
//             const aScore = personasFilter.getScore(FILTER_TYPES.PERSONA_SEARCH, a);
//             const bScore = personasFilter.getScore(FILTER_TYPES.PERSONA_SEARCH, b);
//             return (aScore - bScore);
//         });
//     } else {
//         personas.sort((a, b) => {
//             const aName = String(power_user.personas[a] || a);
//             const bName = String(power_user.personas[b] || b);
//             return power_user.persona_sort_order === 'asc' ? aName.localeCompare(bName) : bName.localeCompare(aName);
//         });
//     }

//     return personas;
// }

// /** Checks the state of the current search, and adds/removes the search sorting option accordingly */
// function verifyPersonaSearchSortRule() {
//     const searchTerm = personasFilter.getFilterData(FILTER_TYPES.PERSONA_SEARCH);
//     const searchOption = $('#persona_sort_order option[value="search"]');
//     const selector = $('#persona_sort_order');
//     const isHidden = searchOption.attr('hidden') !== undefined;

//     // If we have a search term, we are displaying the sorting option for it
//     if (searchTerm && isHidden) {
//         searchOption.removeAttr('hidden');
//         selector.val(searchOption.attr('value'));
//         flashHighlight(selector);
//     }
//     // If search got cleared, we make sure to hide the option and go back to the one before
//     if (!searchTerm) {
//         searchOption.attr('hidden', '');
//         selector.val(power_user.persona_sort_order);
//     }
// }

// /**
//  * Gets a rendered avatar block.
//  * @param {string} name Avatar file name
//  * @returns {JQuery<HTMLElement>} Avatar block
//  */
// function getUserAvatarBlock(name) {
//     const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
//     const template = $('#user_avatar_template .avatar-container').clone();
//     const personaName = power_user.personas[name];
//     const personaDescription = power_user.persona_descriptions[name]?.description;
//     template.find('.ch_name').text(personaName || '[Unnamed Persona]');
//     template.find('.ch_description').text(personaDescription || $('#user_avatar_block').attr('no_desc_text')).toggleClass('text_muted', !personaDescription);
//     template.attr('imgfile', name);
//     template.find('.avatar').attr('imgfile', name).attr('title', name);
//     template.toggleClass('default_persona', name === power_user.default_persona);
//     let avatarUrl = getUserAvatar(name);
//     if (isFirefox) {
//         avatarUrl += '?t=' + Date.now();
//     }
//     template.find('img').attr('src', avatarUrl);
//     $('#user_avatar_block').append(template);
//     return template;
// }

// /**
//  * Gets a list of user avatars.
//  * @param {boolean} doRender Whether to render the list
//  * @param {string} openPageAt Item to be opened at
//  * @returns {Promise<string[]>} List of avatar file names
//  */
// export async function getUserAvatars(doRender = true, openPageAt = '') {
//     const response = await fetch('/api/avatars/get', {
//         method: 'POST',
//         headers: getRequestHeaders(),
//     });
//     if (response.ok) {
//         const allEntities = await response.json();

//         if (!Array.isArray(allEntities)) {
//             return [];
//         }

//         if (!doRender) {
//             return allEntities;
//         }

//         // Before printing the personas, we check if we should enable/disable search sorting
//         verifyPersonaSearchSortRule();

//         let entities = personasFilter.applyFilters(allEntities);
//         entities = sortPersonas(entities);

//         const storageKey = 'Personas_PerPage';
//         const listId = '#user_avatar_block';
//         const perPage = Number(localStorage.getItem(storageKey)) || 5;

//         $('#persona_pagination_container').pagination({
//             dataSource: entities,
//             pageSize: perPage,
//             sizeChangerOptions: [5, 10, 25, 50, 100, 250, 500, 1000],
//             pageRange: 1,
//             pageNumber: savePersonasPage || 1,
//             position: 'top',
//             showPageNumbers: false,
//             showSizeChanger: true,
//             prevText: '<',
//             nextText: '>',
//             formatNavigator: PAGINATION_TEMPLATE,
//             showNavigator: true,
//             callback: function (data) {
//                 $(listId).empty();
//                 for (const item of data) {
//                     $(listId).append(getUserAvatarBlock(item));
//                 }
//                 highlightSelectedAvatar();
//             },
//             afterSizeSelectorChange: function (e) {
//                 localStorage.setItem(storageKey, e.target.value);
//             },
//             afterPaging: function (e) {
//                 savePersonasPage = e;
//             },
//             afterRender: function () {
//                 $(listId).scrollTop(0);
//             },
//         });

//         if (openPageAt) {
//             const avatarIndex = entities.indexOf(openPageAt);
//             const page = Math.floor(avatarIndex / perPage) + 1;

//             if (avatarIndex !== -1) {
//                 $('#persona_pagination_container').pagination('go', page);
//             }
//         }

//         return allEntities;
//     }
// }

// /**
//  * Uploads an avatar file to the server
//  * @param {string} url URL for the avatar file
//  * @param {string} [name] Optional name for the avatar file
//  * @returns {Promise} Promise object representing the AJAX request
//  */
// async function uploadUserAvatar(url, name) {
//     const fetchResult = await fetch(url);
//     const blob = await fetchResult.blob();
//     const file = new File([blob], 'avatar.png', { type: 'image/png' });
//     const formData = new FormData();
//     formData.append('avatar', file);

//     if (name) {
//         formData.append('overwrite_name', name);
//     }

//     return jQuery.ajax({
//         type: 'POST',
//         url: '/api/avatars/upload',
//         data: formData,
//         beforeSend: () => { },
//         cache: false,
//         contentType: false,
//         processData: false,
//         success: async function () {
//             await getUserAvatars(true, name);
//         },
//     });
// }

// async function changeUserAvatar(e) {
//     const form = document.getElementById('form_upload_avatar');

//     if (!(form instanceof HTMLFormElement)) {
//         console.error('Form not found');
//         return;
//     }

//     const file = e.target.files[0];

//     if (!file) {
//         form.reset();
//         return;
//     }

//     const formData = new FormData(form);
//     const dataUrl = await getBase64Async(file);
//     let url = '/api/avatars/upload';

//     if (!power_user.never_resize_avatars) {
//         const confirmation = await callPopup(getCropPopup(dataUrl), 'avatarToCrop', '', { okButton: 'Crop', large: true, wide: true });
//         if (!confirmation) {
//             return;
//         }

//         if (crop_data !== undefined) {
//             url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
//         }
//     }

//     const rawFile = formData.get('avatar');
//     if (rawFile instanceof File) {
//         const convertedFile = await ensureImageFormatSupported(rawFile);
//         formData.set('avatar', convertedFile);
//     }

//     jQuery.ajax({
//         type: 'POST',
//         url: url,
//         data: formData,
//         beforeSend: () => { },
//         cache: false,
//         contentType: false,
//         processData: false,
//         success: async function (data) {
//             // If the user uploaded a new avatar, we want to make sure it's not cached
//             const name = formData.get('overwrite_name');
//             if (name) {
//                 await fetch(getUserAvatar(String(name)), { cache: 'no-cache' });
//                 reloadUserAvatar(true);
//             }

//             if (!name && data.path) {
//                 await getUserAvatars();
//                 await delay(500);
//                 await createPersona(data.path);
//             }

//             await getUserAvatars(true, name || data.path);
//         },
//         error: (jqXHR, exception) => { },
//     });

//     // Will allow to select the same file twice in a row
//     form.reset();
// }

// /**
//  * Prompts the user to create a persona for the uploaded avatar.
//  * @param {string} avatarId User avatar id
//  * @returns {Promise} Promise that resolves when the persona is set
//  */
// export async function createPersona(avatarId) {
//     const personaName = await callPopup('<h3>Enter a name for this persona:</h3>Cancel if you\'re just uploading an avatar.', 'input', '');

//     if (!personaName) {
//         console.debug('User cancelled creating a persona');
//         return;
//     }

//     await delay(500);
//     const personaDescription = await callPopup('<h3>Enter a description for this persona:</h3>You can always add or change it later.', 'input', '', { rows: 4 });

//     initPersona(avatarId, personaName, personaDescription);
//     if (power_user.persona_show_notifications) {
//         toastr.success(`You can now pick ${personaName} as a persona in the Persona Management menu.`, 'Persona Created');
//     }
// }

// async function createDummyPersona() {
//     const personaName = await callPopup('<h3>Enter a name for this persona:</h3>', 'input', '');

//     if (!personaName) {
//         console.debug('User cancelled creating dummy persona');
//         return;
//     }

//     // Date + name (only ASCII) to make it unique
//     const avatarId = `${Date.now()}-${personaName.replace(/[^a-zA-Z0-9]/g, '')}.png`;
//     initPersona(avatarId, personaName, '');
//     await uploadUserAvatar(default_avatar, avatarId);
// }

// /**
//  * Initializes a persona for the given avatar id.
//  * @param {string} avatarId User avatar id
//  * @param {string} personaName Name for the persona
//  * @param {string} personaDescription Optional description for the persona
//  * @returns {void}
//  */
// export function initPersona(avatarId, personaName, personaDescription) {
//     power_user.personas[avatarId] = personaName;
//     power_user.persona_descriptions[avatarId] = {
//         description: personaDescription || '',
//         position: persona_description_positions.IN_PROMPT,
//         depth: DEFAULT_DEPTH,
//         role: DEFAULT_ROLE,
//     };

//     saveSettingsDebounced();
// }

// export async function convertCharacterToPersona(characterId = null) {
//     if (null === characterId) characterId = this_chid;

//     const avatarUrl = characters[characterId]?.avatar;
//     if (!avatarUrl) {
//         console.log('No avatar found for this character');
//         return;
//     }

//     const name = characters[characterId]?.name;
//     let description = characters[characterId]?.description;
//     const overwriteName = `${name} (Persona).png`;

//     if (overwriteName in power_user.personas) {
//         const confirmation = await callPopup('This character exists as a persona already. Are you sure want to overwrite it?', 'confirm', '', { okButton: 'Yes' });

//         if (confirmation === false) {
//             console.log('User cancelled the overwrite of the persona');
//             return;
//         }
//     }

//     if (description.includes('{{char}}') || description.includes('{{user}}')) {
//         await delay(500);
//         const confirmation = await callPopup('This character has a description that uses {{char}} or {{user}} macros. Do you want to swap them in the persona description?', 'confirm', '', { okButton: 'Yes' });

//         if (confirmation) {
//             description = description.replace(/{{char}}/gi, '{{personaChar}}').replace(/{{user}}/gi, '{{personaUser}}');
//             description = description.replace(/{{personaUser}}/gi, '{{char}}').replace(/{{personaChar}}/gi, '{{user}}');
//         }
//     }

//     const thumbnailAvatar = getThumbnailUrl('avatar', avatarUrl);
//     await uploadUserAvatar(thumbnailAvatar, overwriteName);

//     power_user.personas[overwriteName] = name;
//     power_user.persona_descriptions[overwriteName] = {
//         description: description,
//         position: persona_description_positions.IN_PROMPT,
//         depth: DEFAULT_DEPTH,
//         role: DEFAULT_ROLE,
//     };

//     // If the user is currently using this persona, update the description
//     if (user_avatar === overwriteName) {
//         power_user.persona_description = description;
//     }

//     saveSettingsDebounced();

//     console.log('Persona for character created');
//     toastr.success(`You can now select ${name} as a persona in the Persona Management menu.`, 'Persona Created');

//     // Refresh the persona selector
//     await getUserAvatars(true, overwriteName);
//     // Reload the persona description
//     setPersonaDescription();
// }

// /**
//  * Counts the number of tokens in a persona description.
//  */
// const countPersonaDescriptionTokens = debounce(async () => {
//     const description = String($('#persona_description').val());
//     const count = await getTokenCountAsync(description);
//     $('#persona_description_token_count').text(String(count));
// }, debounce_timeout.relaxed);

// export function setPersonaDescription() {
//     if (power_user.persona_description_position === persona_description_positions.AFTER_CHAR) {
//         power_user.persona_description_position = persona_description_positions.IN_PROMPT;
//     }

//     $('#persona_depth_position_settings').toggle(power_user.persona_description_position === persona_description_positions.AT_DEPTH);
//     $('#persona_description').val(power_user.persona_description);
//     $('#persona_depth_value').val(power_user.persona_description_depth ?? DEFAULT_DEPTH);
//     $('#persona_description_position')
//         .val(power_user.persona_description_position)
//         .find(`option[value="${power_user.persona_description_position}"]`)
//         .attr('selected', String(true));
//     $('#persona_depth_role')
//         .val(power_user.persona_description_role)
//         .find(`option[value="${power_user.persona_description_role}"]`)
//         .prop('selected', String(true));
//     countPersonaDescriptionTokens();
// }

// export function autoSelectPersona(name) {
//     for (const [key, value] of Object.entries(power_user.personas)) {
//         if (value === name) {
//             console.log(`Auto-selecting persona ${key} for name ${name}`);
//             setUserAvatar(key);
//             return;
//         }
//     }
// }

// /**
//  * Updates the name of a persona if it exists.
//  * @param {string} avatarId User avatar id
//  * @param {string} newName New name for the persona
//  */
// async function updatePersonaNameIfExists(avatarId, newName) {
//     if (avatarId in power_user.personas) {
//         power_user.personas[avatarId] = newName;
//         console.log(`Updated persona name for ${avatarId} to ${newName}`);
//     } else {
//         power_user.personas[avatarId] = newName;
//         power_user.persona_descriptions[avatarId] = {
//             description: '',
//             position: persona_description_positions.IN_PROMPT,
//             depth: DEFAULT_DEPTH,
//             role: DEFAULT_ROLE,
//         };
//         console.log(`Created persona name for ${avatarId} as ${newName}`);
//     }

//     await getUserAvatars(true, avatarId);
//     saveSettingsDebounced();
// }

// async function bindUserNameToPersona(e) {
//     e?.stopPropagation();
//     const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');

//     if (!avatarId) {
//         console.warn('No avatar id found');
//         return;
//     }

//     const existingPersona = power_user.personas[avatarId];
//     const personaName = await callPopup('<h3>Enter a name for this persona:</h3>(If empty name is provided, this will unbind the name from this avatar)', 'input', existingPersona || '');

//     // If the user clicked cancel, don't do anything
//     if (personaName === false) {
//         return;
//     }

//     if (personaName.length > 0) {
//         // If the user clicked ok and entered a name, bind the name to the persona
//         console.log(`Binding persona ${avatarId} to name ${personaName}`);
//         power_user.personas[avatarId] = personaName;
//         const descriptor = power_user.persona_descriptions[avatarId];
//         const isCurrentPersona = avatarId === user_avatar;

//         // Create a description object if it doesn't exist
//         if (!descriptor) {
//             // If the user is currently using this persona, set the description to the current description
//             power_user.persona_descriptions[avatarId] = {
//                 description: isCurrentPersona ? power_user.persona_description : '',
//                 position: isCurrentPersona ? power_user.persona_description_position : persona_description_positions.IN_PROMPT,
//                 depth: isCurrentPersona ? power_user.persona_description_depth : DEFAULT_DEPTH,
//                 role: isCurrentPersona ? power_user.persona_description_role : DEFAULT_ROLE,
//             };
//         }

//         // If the user is currently using this persona, update the name
//         if (isCurrentPersona) {
//             console.log(`Auto-updating user name to ${personaName}`);
//             setUserName(personaName);
//         }
//     } else {
//         // If the user clicked ok, but didn't enter a name, delete the persona
//         console.log(`Unbinding persona ${avatarId}`);
//         delete power_user.personas[avatarId];
//         delete power_user.persona_descriptions[avatarId];
//     }

//     saveSettingsDebounced();
//     await getUserAvatars(true, avatarId);
//     setPersonaDescription();
// }

// function selectCurrentPersona() {
//     const personaName = power_user.personas[user_avatar];
//     if (personaName) {
//         const lockedPersona = chat_metadata['persona'];
//         if (lockedPersona && lockedPersona !== user_avatar && power_user.persona_show_notifications) {
//             toastr.info(
//                 `To permanently set "${personaName}" as the selected persona, unlock and relock it using the "Lock" button. Otherwise, the selection resets upon reloading the chat.`,
//                 `This chat is locked to a different persona (${power_user.personas[lockedPersona]}).`,
//                 { timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true },
//             );
//         }

//         if (personaName !== name1) {
//             console.log(`Auto-updating user name to ${personaName}`);
//             setUserName(personaName);
//         }

//         const descriptor = power_user.persona_descriptions[user_avatar];

//         if (descriptor) {
//             power_user.persona_description = descriptor.description ?? '';
//             power_user.persona_description_position = descriptor.position ?? persona_description_positions.IN_PROMPT;
//             power_user.persona_description_depth = descriptor.depth ?? DEFAULT_DEPTH;
//             power_user.persona_description_role = descriptor.role ?? DEFAULT_ROLE;
//         } else {
//             power_user.persona_description = '';
//             power_user.persona_description_position = persona_description_positions.IN_PROMPT;
//             power_user.persona_description_depth = DEFAULT_DEPTH;
//             power_user.persona_description_role = DEFAULT_ROLE;
//             power_user.persona_descriptions[user_avatar] = { description: '', position: persona_description_positions.IN_PROMPT, depth: DEFAULT_DEPTH, role: DEFAULT_ROLE };
//         }

//         setPersonaDescription();
//     }
// }

// async function lockUserNameToChat() {
//     if (chat_metadata['persona']) {
//         console.log(`Unlocking persona for this chat ${chat_metadata['persona']}`);
//         delete chat_metadata['persona'];
//         await saveMetadata();
//         if (power_user.persona_show_notifications) {
//             toastr.info('User persona is now unlocked for this chat. Click the "Lock" again to revert.', 'Persona unlocked');
//         }
//         updateUserLockIcon();
//         return;
//     }

//     if (!(user_avatar in power_user.personas)) {
//         console.log(`Creating a new persona ${user_avatar}`);
//         if (power_user.persona_show_notifications) {
//             toastr.info(
//                 'Creating a new persona for currently selected user name and avatar...',
//                 'Persona not set for this avatar',
//                 { timeOut: 10000, extendedTimeOut: 20000 },
//             );
//         }
//         power_user.personas[user_avatar] = name1;
//         power_user.persona_descriptions[user_avatar] = { description: '', position: persona_description_positions.IN_PROMPT };
//     }

//     chat_metadata['persona'] = user_avatar;
//     await saveMetadata();
//     saveSettingsDebounced();
//     console.log(`Locking persona for this chat ${user_avatar}`);
//     if (power_user.persona_show_notifications) {
//         toastr.success(`User persona is locked to ${name1} in this chat`);
//     }
//     updateUserLockIcon();
// }

// async function deleteUserAvatar(e) {
//     e?.stopPropagation();
//     const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');

//     if (!avatarId) {
//         console.warn('No avatar id found');
//         return;
//     }

//     if (avatarId == user_avatar) {
//         console.warn(`User tried to delete their current avatar ${avatarId}`);
//         toastr.warning('You cannot delete the avatar you are currently using', 'Warning');
//         return;
//     }

//     const confirm = await callPopup('<h3>Are you sure you want to delete this avatar?</h3>All information associated with its linked persona will be lost.', 'confirm');

//     if (!confirm) {
//         console.debug('User cancelled deleting avatar');
//         return;
//     }

//     const request = await fetch('/api/avatars/delete', {
//         method: 'POST',
//         headers: getRequestHeaders(),
//         body: JSON.stringify({
//             'avatar': avatarId,
//         }),
//     });

//     if (request.ok) {
//         console.log(`Deleted avatar ${avatarId}`);
//         delete power_user.personas[avatarId];
//         delete power_user.persona_descriptions[avatarId];

//         if (avatarId === power_user.default_persona) {
//             toastr.warning('The default persona was deleted. You will need to set a new default persona.', 'Default persona deleted');
//             power_user.default_persona = null;
//         }

//         if (avatarId === chat_metadata['persona']) {
//             toastr.warning('The locked persona was deleted. You will need to set a new persona for this chat.', 'Persona deleted');
//             delete chat_metadata['persona'];
//             await saveMetadata();
//         }

//         saveSettingsDebounced();
//         await getUserAvatars();
//         updateUserLockIcon();
//     }
// }

// function onPersonaDescriptionInput() {
//     power_user.persona_description = String($('#persona_description').val());
//     countPersonaDescriptionTokens();

//     if (power_user.personas[user_avatar]) {
//         let object = power_user.persona_descriptions[user_avatar];

//         if (!object) {
//             object = {
//                 description: power_user.persona_description,
//                 position: Number($('#persona_description_position').find(':selected').val()),
//                 depth: Number($('#persona_depth_value').val()),
//                 role: Number($('#persona_depth_role').find(':selected').val()),
//             };
//             power_user.persona_descriptions[user_avatar] = object;
//         }

//         object.description = power_user.persona_description;
//     }

//     $(`.avatar-container[imgfile="${user_avatar}"] .ch_description`)
//         .text(power_user.persona_description || $('#user_avatar_block').attr('no_desc_text'))
//         .toggleClass('text_muted', !power_user.persona_description);
//     saveSettingsDebounced();
// }

// function onPersonaDescriptionDepthValueInput() {
//     power_user.persona_description_depth = Number($('#persona_depth_value').val());

//     if (power_user.personas[user_avatar]) {
//         const object = getOrCreatePersonaDescriptor();
//         object.depth = power_user.persona_description_depth;
//     }

//     saveSettingsDebounced();
// }

// function onPersonaDescriptionDepthRoleInput() {
//     power_user.persona_description_role = Number($('#persona_depth_role').find(':selected').val());

//     if (power_user.personas[user_avatar]) {
//         const object = getOrCreatePersonaDescriptor();
//         object.role = power_user.persona_description_role;
//     }

//     saveSettingsDebounced();
// }

// function onPersonaDescriptionPositionInput() {
//     power_user.persona_description_position = Number(
//         $('#persona_description_position').find(':selected').val(),
//     );

//     if (power_user.personas[user_avatar]) {
//         const object = getOrCreatePersonaDescriptor();
//         object.position = power_user.persona_description_position;
//     }

//     saveSettingsDebounced();
//     $('#persona_depth_position_settings').toggle(power_user.persona_description_position === persona_description_positions.AT_DEPTH);
// }

// function getOrCreatePersonaDescriptor() {
//     let object = power_user.persona_descriptions[user_avatar];

//     if (!object) {
//         object = {
//             description: power_user.persona_description,
//             position: power_user.persona_description_position,
//             depth: power_user.persona_description_depth,
//             role: power_user.persona_description_role,
//         };
//         power_user.persona_descriptions[user_avatar] = object;
//     }
//     return object;
// }

// async function setDefaultPersona(e) {
//     e?.stopPropagation();
//     const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');

//     if (!avatarId) {
//         console.warn('No avatar id found');
//         return;
//     }

//     const currentDefault = power_user.default_persona;

//     if (power_user.personas[avatarId] === undefined) {
//         console.warn(`No persona name found for avatar ${avatarId}`);
//         toastr.warning('You must bind a name to this persona before you can set it as the default.', 'Persona name not set');
//         return;
//     }

//     const personaName = power_user.personas[avatarId];

//     if (avatarId === currentDefault) {
//         const confirm = await callPopup('Are you sure you want to remove the default persona?', 'confirm');

//         if (!confirm) {
//             console.debug('User cancelled removing default persona');
//             return;
//         }

//         console.log(`Removing default persona ${avatarId}`);
//         if (power_user.persona_show_notifications) {
//             toastr.info('This persona will no longer be used by default when you open a new chat.', 'Default persona removed');
//         }
//         delete power_user.default_persona;
//     } else {
//         const confirm = await callPopup(`<h3>Are you sure you want to set "${personaName}" as the default persona?</h3>
//         This name and avatar will be used for all new chats, as well as existing chats where the user persona is not locked.`, 'confirm');

//         if (!confirm) {
//             console.debug('User cancelled setting default persona');
//             return;
//         }

//         power_user.default_persona = avatarId;
//         if (power_user.persona_show_notifications) {
//             toastr.success('This persona will be used by default when you open a new chat.', `Default persona set to ${personaName}`);
//         }
//     }

//     saveSettingsDebounced();
//     await getUserAvatars(true, avatarId);
// }

// function updateUserLockIcon() {
//     const hasLock = !!chat_metadata['persona'];
//     $('#lock_user_name').toggleClass('fa-unlock', !hasLock);
//     $('#lock_user_name').toggleClass('fa-lock', hasLock);
// }

// async function setChatLockedPersona() {
//     // Define a persona for this chat
//     let chatPersona = '';

//     if (chat_metadata['persona']) {
//         // If persona is locked in chat metadata, select it
//         console.log(`Using locked persona ${chat_metadata['persona']}`);
//         chatPersona = chat_metadata['persona'];
//     } else if (power_user.default_persona) {
//         // If default persona is set, select it
//         console.log(`Using default persona ${power_user.default_persona}`);
//         chatPersona = power_user.default_persona;
//     }

//     // No persona set: user current settings
//     if (!chatPersona) {
//         console.debug('No default or locked persona set for this chat');
//         return;
//     }

//     // Find the avatar file
//     const userAvatars = await getUserAvatars(false);

//     // Avatar missing (persona deleted)
//     if (chat_metadata['persona'] && !userAvatars.includes(chatPersona)) {
//         console.warn('Persona avatar not found, unlocking persona');
//         delete chat_metadata['persona'];
//         updateUserLockIcon();
//         return;
//     }

//     // Default persona missing
//     if (power_user.default_persona && !userAvatars.includes(power_user.default_persona)) {
//         console.warn('Default persona avatar not found, clearing default persona');
//         power_user.default_persona = null;
//         saveSettingsDebounced();
//         return;
//     }

//     // Persona avatar found, select it
//     setUserAvatar(chatPersona);
//     updateUserLockIcon();
// }

// function onBackupPersonas() {
//     const timestamp = new Date().toISOString().split('T')[0].replace(/-/g, '');
//     const filename = `personas_${timestamp}.json`;
//     const data = JSON.stringify({
//         'personas': power_user.personas,
//         'persona_descriptions': power_user.persona_descriptions,
//         'default_persona': power_user.default_persona,
//     }, null, 2);

//     const blob = new Blob([data], { type: 'application/json' });
//     download(blob, filename, 'application/json');
// }

// async function onPersonasRestoreInput(e) {
//     const file = e.target.files[0];

//     if (!file) {
//         console.debug('No file selected');
//         return;
//     }

//     const data = await parseJsonFile(file);

//     if (!data) {
//         toastr.warning('Invalid file selected', 'Persona Management');
//         console.debug('Invalid file selected');
//         return;
//     }

//     if (!data.personas || !data.persona_descriptions || typeof data.personas !== 'object' || typeof data.persona_descriptions !== 'object') {
//         toastr.warning('Invalid file format', 'Persona Management');
//         console.debug('Invalid file selected');
//         return;
//     }

//     const avatarsList = await getUserAvatars(false);
//     const warnings = [];

//     // Merge personas with existing ones
//     for (const [key, value] of Object.entries(data.personas)) {
//         if (key in power_user.personas) {
//             warnings.push(`Persona "${key}" (${value}) already exists, skipping`);
//             continue;
//         }

//         power_user.personas[key] = value;

//         // If the avatar is missing, upload it
//         if (!avatarsList.includes(key)) {
//             warnings.push(`Persona image "${key}" (${value}) is missing, uploading default avatar`);
//             await uploadUserAvatar(default_avatar, key);
//         }
//     }

//     // Merge persona descriptions with existing ones
//     for (const [key, value] of Object.entries(data.persona_descriptions)) {
//         if (key in power_user.persona_descriptions) {
//             warnings.push(`Persona description for "${key}" (${power_user.personas[key]}) already exists, skipping`);
//             continue;
//         }

//         if (!power_user.personas[key]) {
//             warnings.push(`Persona for "${key}" does not exist, skipping`);
//             continue;
//         }

//         power_user.persona_descriptions[key] = value;
//     }

//     if (data.default_persona) {
//         if (data.default_persona in power_user.personas) {
//             power_user.default_persona = data.default_persona;
//         } else {
//             warnings.push(`Default persona "${data.default_persona}" does not exist, skipping`);
//         }
//     }

//     if (warnings.length) {
//         toastr.success('Personas restored with warnings. Check console for details.');
//         console.warn(`PERSONA RESTORE REPORT\n====================\n${warnings.join('\n')}`);
//     } else {
//         toastr.success('Personas restored successfully.');
//     }

//     await getUserAvatars();
//     setPersonaDescription();
//     saveSettingsDebounced();
//     $('#personas_restore_input').val('');
// }

// async function syncUserNameToPersona() {
//     const confirmation = await callPopup(`<h3>Are you sure?</h3>All user-sent messages in this chat will be attributed to ${name1}.`, 'confirm');

//     if (!confirmation) {
//         return;
//     }

//     for (const mes of chat) {
//         if (mes.is_user) {
//             mes.name = name1;
//             mes.force_avatar = getUserAvatar(user_avatar);
//         }
//     }

//     await saveChatConditional();
//     await reloadCurrentChat();
// }

// export function retriggerFirstMessageOnEmptyChat() {
//     if (this_chid >= 0 && !selected_group && chat.length === 1) {
//         $('#firstmessage_textarea').trigger('input');
//     }
// }

// export function initPersonas() {
//     $(document).on('click', '.bind_user_name', bindUserNameToPersona);
//     $(document).on('click', '.set_default_persona', setDefaultPersona);
//     $(document).on('click', '.delete_avatar', deleteUserAvatar);
//     $('#lock_user_name').on('click', lockUserNameToChat);
//     $('#create_dummy_persona').on('click', createDummyPersona);
//     $('#persona_description').on('input', onPersonaDescriptionInput);
//     $('#persona_description_position').on('input', onPersonaDescriptionPositionInput);
//     $('#persona_depth_value').on('input', onPersonaDescriptionDepthValueInput);
//     $('#persona_depth_role').on('input', onPersonaDescriptionDepthRoleInput);
//     $('#personas_backup').on('click', onBackupPersonas);
//     $('#personas_restore').on('click', () => $('#personas_restore_input').trigger('click'));
//     $('#personas_restore_input').on('change', onPersonasRestoreInput);
//     $('#persona_sort_order').val(power_user.persona_sort_order).on('input', function () {
//         const value = String($(this).val());
//         // Save sort order, but do not save search sorting, as this is a temporary sorting option
//         if (value !== 'search') power_user.persona_sort_order = value;
//         getUserAvatars(true, user_avatar);
//         saveSettingsDebounced();
//     });
//     $('#persona_grid_toggle').on('click', () => {
//         const state = localStorage.getItem(GRID_STORAGE_KEY) === 'true';
//         localStorage.setItem(GRID_STORAGE_KEY, String(!state));
//         switchPersonaGridView();
//     });

//     const debouncedPersonaSearch = debounce((searchQuery) => {
//         personasFilter.setFilterData(FILTER_TYPES.PERSONA_SEARCH, searchQuery);
//     });

//     $('#persona_search_bar').on('input', function () {
//         const searchQuery = String($(this).val());
//         debouncedPersonaSearch(searchQuery);
//     });

//     $('#sync_name_button').on('click', syncUserNameToPersona);
//     $('#avatar_upload_file').on('change', changeUserAvatar);

//     $(document).on('click', '#user_avatar_block .avatar-container', function () {
//         const imgfile = $(this).attr('imgfile');
//         setUserAvatar(imgfile);

//         // force firstMes {{user}} update on persona switch
//         retriggerFirstMessageOnEmptyChat();
//     });

//     $('#your_name_button').click(async function () {
//         const userName = String($('#your_name').val()).trim();
//         setUserName(userName);
//         await updatePersonaNameIfExists(user_avatar, userName);
//         retriggerFirstMessageOnEmptyChat();
//     });

//     $(document).on('click', '#user_avatar_block .avatar_upload', function () {
//         $('#avatar_upload_overwrite').val('');
//         $('#avatar_upload_file').trigger('click');
//     });

//     $(document).on('click', '#user_avatar_block .set_persona_image', function (e) {
//         e.stopPropagation();
//         const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');

//         if (!avatarId) {
//             console.log('no imgfile');
//             return;
//         }

//         $('#avatar_upload_overwrite').val(avatarId);
//         $('#avatar_upload_file').trigger('click');
//     });

//     eventSource.on('charManagementDropdown', (target) => {
//         if (target === 'convert_to_persona') {
//             convertCharacterToPersona();
//         }
//     });
//     eventSource.on(event_types.CHAT_CHANGED, setChatLockedPersona);
//     switchPersonaGridView();
// }
